package org.zls.client;

import java.util.ArrayList;

import org.zls.client.service.ServerService;

import com.google.gwt.core.client.EntryPoint;  
import com.google.gwt.user.client.ui.HTML;  
  
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.HistoryListener;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.MultiWordSuggestOracle;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.VerticalPanel;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */

// TODO: Generally, we want to have Loading spinners or something when waiting
// for critical asynchoronous calls (e.g. search box data).
public class HSpot implements EntryPoint, HistoryListener {

	private static final Tab.Images images = (Tab.Images) GWT
			.create(Tab.Images.class);

	private Tab curTab;
	private SearchBox box;
	private Tab.TabInfo curInfo;
	private HTML description = new HTML();
	private TabList list = new TabList(images);
	private VerticalPanel panel = new VerticalPanel();

	public void onModuleLoad() {
		initSearchBox();
		initTabs();
		initPanel();
	}

	public void show(Tab.TabInfo info, boolean affectHistory) {
		if (info == curInfo) {
			return;
		}

		curInfo = info;

		if (curTab != null) {
			curTab.onHide();
			panel.remove(curTab);
		}

		info.setTitle();
		curTab = info.getInstance();
		list.setTabSelection(info.getName());
		description.setHTML(info.getDescription());

		if (affectHistory) {
			History.newItem(info.getName());
		}

		DOM.setStyleAttribute(description.getElement(), "backgroundColor", info
				.getColor());

		curTab.setVisible(false);
		panel.add(curTab);
		panel.setCellHorizontalAlignment(curTab, VerticalPanel.ALIGN_CENTER);
		curTab.setVisible(true);
		curTab.onShow();
	}

	private void initSearchBox() {
		box = new SearchBox() {

			public void handleSearch(String query) {
				((SearchTab) list.find("Search").getInstance()).update(query);
				show(list.find("Search"), false);
			}

			public MultiWordSuggestOracle populateSuggestBox() {
				final MultiWordSuggestOracle oracle = new MultiWordSuggestOracle();

				ServerService.Util.getInstance().populateSearchBox(
						new AsyncCallback<ArrayList<String>>() {

							public void onFailure(Throwable arg0) {
								Window
										.alert("ERROR: Asynchronous Call failed from SearchBox.populateSearchBox().");
							}

							public void onSuccess(ArrayList<String> arg0) {
								oracle.addAll(arg0);
							}
						});
				return oracle;
			}
		};
	}

	private void initTabs() {
		list.addTab(WelcomeTab.init());
		list.addTab(SearchTab.init());
		list.addTab(MyCoursesTab.init());
		list.addTab(FeedbackTab.init());
		list.addTab(AboutTab.init());
		list.addTab(SeanTab.init());
		//list.addTab(BennyTab.init());
	}

	private void initPanel() {

		panel.add(box);
		panel.setCellHorizontalAlignment(box, HorizontalPanel.ALIGN_CENTER);
		panel.add(list);
		panel.add(description);
		panel.setWidth("100%");

		description.setStyleName("hu-Info");

		History.addHistoryListener(this);
		RootPanel.get().add(panel);

		String initToken = History.getToken();
		if (initToken.length() > 0) {
			onHistoryChanged(initToken);
		} else {
			showInfo();
		}
	}

	private void showInfo() {
		show(list.find("Welcome"), false);
	}

	public void onHistoryChanged(String token) {

		Tab.TabInfo info = list.find(token);
		if (info == null) {
			showInfo();
			return;
		}

		show(info, false);
	}	
}